use crate::{common, tables::device::TbDevice};
use actix_web::{delete, get, post, web, HttpResponse, Responder};
use serde::{Deserialize, Serialize};
use serde_json::json;

#[get("")]
async fn get(page: web::Query<common::QueryPage>) -> impl Responder {
    common::ResData::<TbDevice>::from_page(TbDevice::get_devices(&page).await).resp_json()
}

#[post("")]
async fn post(data: web::Json<TbDevice>) -> HttpResponse {
    HttpResponse::Ok().json(match TbDevice::update_device(&data).await {
        Ok(_) => json!({
            "success": true,
            "errorMessage": "操作成功"
        }),
        Err(e) => json!({
            "success": false,
            "errorMessage": e.to_string().as_str()
        }),
    })
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Delete {
    pub id: String,
}

#[delete("")]
async fn delete(data: web::Json<Delete>) -> HttpResponse {
    HttpResponse::Ok().json(match TbDevice::delete_device(&data).await {
        Ok(_) => json!({
            "success": true,
            "errorMessage": "操作成功"
        }),
        Err(e) => json!({
            "success": false,
            "errorMessage": e.to_string().as_str()
        }),
    })
}

pub fn routes(cfg: &mut web::ServiceConfig) {
    cfg.service(
        web::scope("/device")
            .service(get)
            .service(post)
            .service(delete),
    );
}

#[cfg(test)]
pub mod tests {
    use crate::{handlers::device, utils::mysql};
    use actix_web::{test, App};
    use serde_json::{json, Value};

    #[actix_web::test]
    async fn test_get_netpoints() {
        mysql::init_pool().await;

        let app = test::init_service(App::new().configure(device::routes)).await;

        let req = test::TestRequest::get().uri("/device").to_request();

        let resp = test::call_service(&app, req).await;
        let status = resp.status();
        println!("resp status is {:?}", status);
        let resp_body = test::read_body(resp).await;
        let json_value: Value = serde_json::from_slice(&resp_body).unwrap();
        println!("restp body is {}", json_value);
        assert!(status.is_success());
    }

    #[actix_web::test]
    async fn test_update_device() {
        mysql::init_pool().await;

        let app = test::init_service(App::new().configure(device::routes)).await;

        let req = test::TestRequest::post()
            .uri("/device")
            .set_json(json!({"id":"0", "authid":"1"}))
            .to_request();

        let resp = test::call_service(&app, req).await;
        let status = resp.status();
        println!("resp status is {:?}", status);
        let resp_body = test::read_body(resp).await;
        // let json_value: Value = serde_json::from_slice(&resp_body).unwrap();
        println!("restp body is {:?}", resp_body);
        assert!(status.is_success());
    }

    #[actix_web::test]
    async fn test_delete_device() {
        mysql::init_pool().await;

        let app = test::init_service(App::new().configure(device::routes)).await;

        let req = test::TestRequest::delete()
            .uri("/device")
            .set_json(json!({"id":"0"}))
            .to_request();

        let resp = test::call_service(&app, req).await;
        let status = resp.status();
        println!("resp status is {:?}", status);
        let resp_body = test::read_body(resp).await;
        let json_value: Value = serde_json::from_slice(&resp_body).unwrap();
        println!("restp body is {:?}", json_value);
        assert!(status.is_success());
    }
}
